//
//  HDMapView.m
//  HDMapKit
//
//  Created by Liuzhuan on 13-4-8.
//  Copyright (c) 2013年 hengdawb. All rights reserved.
//

#import "HDMapView.h"
#import "HDTiledView.h"
#import "HDAnnotationView.h"
#import "HDDeclare.h"

#define kStandardUIScrollViewAnimationTime (int64_t)0.10
@interface HDMapView ()<HDTiledViewDelegate,UIGestureRecognizerDelegate,AnnotationViewDelegate>
@property (nonatomic, strong) UITapGestureRecognizer *singleTapGestureRecognizer;
@property (nonatomic, strong) UITapGestureRecognizer *doubleTapGestureRecognizer;
@property (nonatomic, strong) UITapGestureRecognizer *twoFingerTapGestureRecognizer;

@end

@implementation HDMapView
{
    HDTiledView *_tiledView;
    UIImageView *_routeImageView;
}

-(void)layoutIfNeeded
{
    [super layoutIfNeeded];
    
//    [_tiledView setNeedsLayout];
    [_tiledView setNeedsDisplay];
}

- (id)initWithFrame:(CGRect)frame contentSize:(CGSize)contentSize
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
        self.delegate = self;
        self.backgroundColor = [UIColor clearColor];
        self.contentSize = contentSize;
        self.minimumZoomScale = 1.0;
        self.levelsOfZoom = 2;
        self.zoomsInOnDoubleTap = YES;
        self.zoomsOutOnTwoFingerTap = YES;
        self.centerSingleTap = YES;
        self.orignalSize = contentSize;

        _tiledView = [[HDTiledView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.contentSize.width, self.contentSize.height)];
        _tiledView.delegate = self;
        [self addSubview:_tiledView];
        
        _singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                              action:@selector(singleTapReceived:)];
        _singleTapGestureRecognizer.numberOfTapsRequired = 1;
        [_tiledView addGestureRecognizer:_singleTapGestureRecognizer];
        
        _doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                              action:@selector(doubleTapReceived:)];
        _doubleTapGestureRecognizer.numberOfTapsRequired = 2;
        [_tiledView addGestureRecognizer:_doubleTapGestureRecognizer];
        
        [_singleTapGestureRecognizer requireGestureRecognizerToFail:_doubleTapGestureRecognizer];
        
        _twoFingerTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(twoFingerTapReceived:)];
        _twoFingerTapGestureRecognizer.numberOfTouchesRequired = 2;
        _twoFingerTapGestureRecognizer.numberOfTapsRequired = 1;
        [_tiledView addGestureRecognizer:_twoFingerTapGestureRecognizer];
        
        //NSLog(@"mapViewOriginalFrame:%@",NSStringFromCGRect(self.frame));
    }
    return self;
}

-(void)dealloc
{
    _tiledView.delegate = nil;
    
    if (_pinAnnotations) {
        for (HDAnnotation *annotation in _pinAnnotations) {
            [self removeObserver:annotation forKeyPath:@"contentSize"];
        }
    }
    
    if (_routeImageView != nil)
    {
        [_routeImageView removeFromSuperview];
        _routeImageView = nil;
    }
}

#pragma mark - MapRoute Methods
- (void)myRouteImage:(NSString *)routeName
{
    if (_routeImageView != nil)
    {
        [_routeImageView removeFromSuperview];
        _routeImageView = nil;
        return;
    }
    _routeImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.contentSize.width, self.contentSize.height)];
    UIImage *myImage = [UIImage imageWithContentsOfFile:routeName];//[UIImage imageNamed:routeName];
    _routeImageView.image = myImage;
    [self insertSubview:_routeImageView atIndex:1];
}

- (void)hideRouteView
{
    if (!_routeImageView.hidden)
    {
        _routeImageView.hidden = YES;
    }
}

#pragma mark - location Methods

- (void)locationPin:(NSString *)number
{
    for (HDAnnotationView *tempView in self.pinAnnotations) {
        NSString *imageString;
        if ([tempView.annotation.identify isEqualToString:number]) {
            
            imageString = @"pinGreen.png";
        }
        else
        {
            imageString = @"pinPurple.png";
        }
        
        dispatch_async(dispatch_get_main_queue(),^{
            [self bringSubviewToFront:tempView];
            [tempView setImage:[UIImage imageNamed:imageString] forState:UIControlStateNormal];
            [self bringSubviewToFront:tempView];
        });
        
    }
    
    [self layoutSubviews];
}

- (void)locationMine:(NSString *)myInfo
           andFriend:(NSString *)friendInfo
{
    dispatch_async(dispatch_get_main_queue(), ^{
        for (int i = 0; i< [[self subviews] count]; i++)
        {
            UIView *view = [[self subviews]objectAtIndex:i];
            if ([view isKindOfClass:[HDAnnotationView class]])
            {
                HDAnnotationView *temp = (HDAnnotationView *)view;
                if ([temp.annotation.identify intValue] == [myInfo intValue])
                {
                    [temp setImage:[UIImage imageNamed:@"pinRed.png"] forState:UIControlStateNormal];
                }
                else if ([temp.annotation.identify intValue] == [friendInfo intValue])
                {
                    [temp setImage:[UIImage imageNamed:@"pinGreen.png"] forState:UIControlStateNormal];
                }
                else
                {
                    [temp setImage:[UIImage imageNamed:@"pinPurple.png"] forState:UIControlStateNormal];
                }
                
            }
            
        }
        
    });
    
}

#pragma mark - AnnotationPin Methods

-(void)updatePinPositionWith:(CGPoint)point
{
    for (HDAnnotationView *view in self.pinAnnotations) {
        HDAnnotation *ann = view.annotation;
        ann.point = point;
        dispatch_async(dispatch_get_main_queue(), ^{
            [UIView animateWithDuration:1.0 animations:^{
                view.center = CGPointMake(point.x*self.zoomScale, point.y*self.zoomScale);
            }];
        });
    }
}

-(void)annotationShowHeighWith:(NSString *)exhibit_id
{
    [self allAnnotationsShowNormal];
    
    for (HDAnnotationView *view in self.pinAnnotations) {
        if ([view.annotation.identify isEqualToString:exhibit_id]) {
            [view showHeigh];
            
            [self bringSubviewToFront:view];
            
            HDAnnotation *annotation = view.annotation;
            CGPoint nowPoint = CGPointMake(annotation.point.x*self.zoomScale, annotation.point.y*self.zoomScale);
            CGPoint convertPoint = [self convertPoint:nowPoint toView:_tiledView];
            [self setContentCenter:convertPoint animated:YES];
        }
    }
}

-(void)allAnnotationsShowNormal
{
    for (HDAnnotationView *view in self.pinAnnotations) {
        [view showNormal];
    }
}

- (void)addAnnotation:(HDAnnotation *)annotation animated:(BOOL)animate {
    
    HDAnnotationView *pinAnnotation = [[HDAnnotationView alloc] initWithAnnotation:annotation animated:animate];
    pinAnnotation.myDelegate = self;
    [self addSubview:pinAnnotation];
    
    if (!_pinAnnotations) {
        _pinAnnotations = [[NSMutableArray alloc] init];
    }
    
    [self.pinAnnotations addObject:pinAnnotation];
    [self addObserver:pinAnnotation
           forKeyPath:@"contentSize"
              options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
              context:nil];
}

- (void)addAnnotations:(NSArray *)annotations animated:(BOOL)animate
{
    for (HDAnnotation *annotation in annotations)
    {
        [self addAnnotation:annotation animated:animate];
    }
    
}

- (void)removeAllAnnatations:(BOOL)animate
{
    for (HDAnnotationView *annotation in _pinAnnotations)
    {
        [annotation removeFromSuperview];
        [self removeObserver:annotation forKeyPath:@"contentSize"];
    }
    [self.pinAnnotations removeAllObjects];
    [self setZoomScale:1 animated:YES];
}

#pragma mark - Annotation Delegate

-(void)heighlightAnnotationWith:(HDAnnotationView *)annotationView
{
    HDAnnotation *annotation = annotationView.annotation;
    
    [self bringSubviewToFront:annotationView];
    
    [self.mapViewdelegate annClickedWith:annotation];
    
    [self allAnnotationsShowNormal];
    
    CGPoint nowPoint = CGPointMake(annotation.point.x*self.zoomScale, annotation.point.y*self.zoomScale);
    CGPoint convertPoint = [self convertPoint:nowPoint toView:_tiledView];
    [self setContentCenter:convertPoint animated:YES];
}

#pragma mark - UIScrolViewDelegate

- (UIView *)viewForZoomingInScrollView:(__unused UIScrollView *)scrollView
{
    return _tiledView;
}

- (void)scrollViewDidZoom:(__unused UIScrollView *)scrollView
{
    if ([self.mapViewdelegate respondsToSelector:@selector(mapViewDidZoom:)])
    {
        [self.mapViewdelegate mapViewDidZoom:self];
    }
     _routeImageView.frame = CGRectMake(0, 0, self.contentSize.width, self.contentSize.height);
}

- (void)scrollViewDidScroll:(__unused UIScrollView *)scrollView
{
    //[[NSNotificationCenter defaultCenter] postNotificationName:hideBottomViewNoti object:nil];
}   

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    //[[NSNotificationCenter defaultCenter] postNotificationName:hideBottomViewNoti object:nil];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //NSLog(@"scrollViewDidEndScrollingAnimation");
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
    
}

#pragma mark - Gesture Suport

- (void)singleTapReceived:(UITapGestureRecognizer *)gestureRecognizer
{
//    NSLog(@"singleTapReceived");
    
    if (self.centerSingleTap)
    {
//        [self setContentCenter:[gestureRecognizer locationInView:_tiledView]
//                      animated:YES];
    }
    
    if ([self.mapViewdelegate respondsToSelector:@selector(mapView:didReceiveSingleTap:)])
    {
        [self.mapViewdelegate mapView:self
                  didReceiveSingleTap:gestureRecognizer];
    }
}

- (void)doubleTapReceived:(UITapGestureRecognizer *)gestureRecognizer
{
//    NSLog(@"doubleTapReceived");
    
    if (self.zoomScale >= self.maximumZoomScale)
    {
        [self setZoomScale:1.0f animated:YES];
        return;
    }
    
    if (self.zoomsInOnDoubleTap)
    {
        CGFloat newZoom = MIN(powf(2, (log2f(self.zoomScale) + 1.0f)), self.maximumZoomScale); //zoom in one level of detail
        
        [self setZoomScale:newZoom animated:YES];
    }
    
    if ([self.mapViewdelegate respondsToSelector:@selector(mapView:didReceiveDoubleTap:)])
    {
        [self.mapViewdelegate mapView:self
                  didReceiveDoubleTap:gestureRecognizer];
    }
}

- (void)twoFingerTapReceived:(UITapGestureRecognizer *)gestureRecognizer
{
//    NSLog(@"twoFingerTapReceived");
    
    if (self.zoomsOutOnTwoFingerTap)
    {
        float newZoom = MAX(powf(2, (log2f(self.zoomScale) - 1.0f)), self.minimumZoomScale); //zoom out one level of detail
        
        [self setZoomScale:newZoom animated:YES];
    }
}

#pragma mark - HDMapView

- (void)setLevelsOfZoom:(size_t)levelsOfZoom
{
    _levelsOfZoom = levelsOfZoom;
    self.maximumZoomScale = (float)powf(2.0f, MAX(0.0f, levelsOfZoom));
}

- (void)setLevelsOfDetail:(size_t)levelsOfDetail
{
    if (levelsOfDetail == 1) //NSLog(@"Note: Setting levelsOfDetail to 1 causes strange behaviour");
    
    _levelsOfDetail = levelsOfDetail;
    [_tiledView setNumberOfZoomLevels:levelsOfDetail];
}

//防止点位太靠近边框导致点位滑动到中心点时界面出现空白
- (void)setContentCenter:(CGPoint)center animated:(BOOL)animated
{
    CGPoint new_contentOffset = self.contentOffset;
    
    if (self.contentSize.width > self.bounds.size.width)
    {
        new_contentOffset.x = MAX(0.0f, (center.x * self.zoomScale) - (self.bounds.size.width / 2.0f));
        new_contentOffset.x = MIN(new_contentOffset.x, (self.contentSize.width - self.bounds.size.width));
    }
    
    if (self.contentSize.height > self.bounds.size.height)
    {
        new_contentOffset.y = MAX(0.0f, (center.y * self.zoomScale) - (self.bounds.size.height / 2.0f));
        new_contentOffset.y = MIN(new_contentOffset.y, (self.contentSize.height - self.bounds.size.height));
        
        // 处理地图上面离naviBar近的大头针点击后上移的问题
        if (new_contentOffset.y <= 0)
        {
            new_contentOffset.y = self.contentOffset.y;
        }
        
    }
    
    [self setContentOffset:new_contentOffset animated:animated];
}

#pragma mark - HDTiledViewDelegate

- (UIImage *)tiledView:(__unused HDTiledView *)tiledView
           imageForRow:(NSInteger)row
                column:(NSInteger)column
                 scale:(NSInteger)scale
{
    return [self.dataSource  mapView:self
                         imageForRow:row
                              column:column
                               scale:scale];
}

@end
